package com.ygqh.baby.service.impl;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.mapper.YgUserPrizeMapper;
import com.ygqh.baby.model.PrizeItem;
import com.ygqh.baby.model.PrizeItem.Type;
import com.ygqh.baby.model.YgSkuInfo;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class YgUserPrizeServiceImpl implements YgUserPrizeService {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private YgUserPrizeMapper ygUserPrizeMapper;
	@Autowired
	private YgCouponService ygCouponService;
	@Autowired
	private YgCardCouponService ygCardCouponService;
	@Autowired
	private YgCardCouponDetailService ygCardCouponDetailService;
	@Autowired
	private YgDrawPrizeRecordService ygDrawPrizeRecordService;
	@Autowired
	private YgSkuService ygSkuService;
	@Autowired
	private YgOrderService ygOrderService;
	@Autowired
	private YgProductService ygProductService;

	@Override
	public List<YgUserPrize> find() {
		YgUserPrizeExample example = new YgUserPrizeExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ygUserPrizeMapper.selectByExample(example);
	}

	@Override
	public int findCount() {
		YgUserPrizeExample example = new YgUserPrizeExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ygUserPrizeMapper.countByExample(example);
	}

	@Override
	public YgUserPrize findById(Long id) {
		return ygUserPrizeMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(YgUserPrize ygUserPrize) {
		return ygUserPrizeMapper.insertSelective(ygUserPrize);
	}

	@Override
	public int update(YgUserPrize ygUserPrize) {
		return ygUserPrizeMapper.updateByPrimaryKeySelective(ygUserPrize);
	}

	@Override
	public ResultSet<YgUserPrize> search(QueryInfo queryInfo, String q) {
		List<YgUserPrize> list = ygUserPrizeMapper.selectSuper(queryInfo, q);
		int count = ygUserPrizeMapper.countSuper(q);
		ResultSet<YgUserPrize> resultSet = new ResultSet<YgUserPrize>(count, list);
		return resultSet;
	}

	@Override
	public int deleteSoft(Long[] ids) {
		Assert.notEmpty(ids);
		YgUserPrizeExample example = new YgUserPrizeExample();
		example.createCriteria().andIdIn(Arrays.asList(ids));
		YgUserPrize record = new YgUserPrize();
		record.setStatus(DataStatus.Delete);

		return ygUserPrizeMapper.updateByExampleSelective(record, example);
	}

	@Override
	public int deleteSoft(Long id) {
		return this.deleteSoft(new Long[] { id });
	}

	@Override
	public int saveOrUpdate(YgUserPrize ygUserPrize) {
		int r = 0;
		if (ygUserPrize.getId() != null) {
			r = this.update(ygUserPrize);
		} else {
			r = this.save(ygUserPrize);
		}
		return r;
	}

	@Override
	public List<YgUserPrize> findPrizeItemByUserId(Long userId, Type type, String sourceCode) {
		return ygUserPrizeMapper.selectPrizeItemByUserId(userId, type, sourceCode);

	}

	@Override
	public int writeBackCount(PrizeItem prizeItem, Long userId, String sourceCode) {
		Boolean existPrize = ygUserPrizeMapper.isExistPrize(prizeItem, userId, sourceCode);

		BigDecimal count = prizeItem.getThisRate();
		if (!prizeItem.getType().equals(Type.Goods))
			count = new BigDecimal("1");
		prizeItem.setThisRate(count);
		if (existPrize) {
			// 存在 update
			return ygUserPrizeMapper.writeBackCount(prizeItem, userId, sourceCode);
		} else {
			// 不存在新增
			this.addUserPrize(prizeItem, userId, sourceCode);
		}

		return 1;
	}

	private void addUserPrize(PrizeItem prizeItem, Long userId, String sourceCode) {
		YgUserPrize prize = new YgUserPrize(sourceCode, userId, prizeItem.getType(), prizeItem.getContent(), prizeItem.getThisRate(), "");
		if (prizeItem.getType().equals(Type.Goods)) {
			prize.setRelationId(Long.valueOf(prizeItem.getRelationCode()));
		} else if (prizeItem.getType().equals(Type.Balance)) {
			prize.setPrice(new BigDecimal(prizeItem.getRelationCode()));
			prize.setExchangeCount(prize.getCount().intValue());
		} else {
			prize.setRelationId(Long.parseLong(prizeItem.getRelationCode()));
			prize.setExchangeCount(prize.getCount().intValue());
		}
		this.save(prize);

	}

	@Override
	public Message cashPrize(Long priziId, BigDecimal quantity, YgUser user, YgUserAddress address) {
		YgUserPrize prize = this.findById(priziId);
		if (prize == null || !prize.getUserId().equals(user.getId())) {
			return Message.error("奖品有误。", priziId);
		}
		if (quantity.compareTo(prize.getCount()) < 0) {
			return Message.error("兑换数量有误，请重试。", priziId);
		}
		Date date = new Date();

		int hasCashCount = ygDrawPrizeRecordService.findCashCountByUserId(user.getId(), null, DateConvertUtils.getMonthStartDate(date),
				DateConvertUtils.getMonthEndDate(date), true);
		if (hasCashCount >= 3) {
			return Message.error("亲，每月限兑换3次", priziId);
		}
		YgCardCoupon card = ygCardCouponService.getDrawPrizeCard(CardMode.Goods);
		if (card == null) {
			return Message.error("无此卡券。", priziId);
		}
		return ygCardCouponDetailService.generateCardCoupon(user.getId(), card.getId(), priziId, "cashPrize");
	}

	@Override
	public Message generateCardCoupon(Long userId, Long cardId,String sourceCode) {
		BigDecimal one = new BigDecimal("1");
		BigDecimal count = ygDrawPrizeRecordService.getGoodsPrizeCount(userId,sourceCode);
		if (count.compareTo(one) < 0) {
			return Message.error("不满足兑换条件", count);
		}
		Date date = new Date();

		int hasCashCount = ygDrawPrizeRecordService.findCashCountByUserId(userId, sourceCode, DateConvertUtils.getMonthStartDate(date),
				DateConvertUtils.getMonthEndDate(date), true);
		if (hasCashCount >= 3) {
			return Message.error("亲，每月限兑换3次", cardId);
		}
		Message message = ygCardCouponDetailService.generateCardCoupon(userId, cardId, null, "DrawPrice");
		if (message.getType().equals(Message.Type.success)) {

			ygDrawPrizeRecordService.addCashRecord(userId, cardId, one,sourceCode);
		}
		return message;
	}

	@Override
	public Message cashPrize(Long skuId, String source, YgUserAddress address, String platformNo, AppType appType) {
		List<YgUserPrize> userPrizeList = this.findPrizeItemByUserId(address.getUserId(), Type.Goods, source);
		if (CollectionUtils.isEmpty(userPrizeList)) {
			logger.error("【转盘抽奖】前端调用接口异常，查询不到用户实物中奖记录，skuId={}, userId={}, source={}",
					skuId, address.getUserId(), source);
			return Message.error("系统异常，请稍后重试或联系客服", null);
		}
		YgSkuInfo skuInfo = ygSkuService.findSkuInfoById(skuId);
		List<Map<String, Object>> products = ygProductService.findProductByGroupId(0L, skuInfo.getGroupId());
		List<Long> productIdList = products.stream().map(o -> Long.valueOf(o.get("id").toString()))
				.collect(Collectors.toList());
		userPrizeList = userPrizeList.stream().
				filter(o -> productIdList.contains(o.getRelationId()) &&
								o.getExchangeCount().compareTo(o.getCount().intValue()) < 0)
				.collect(Collectors.toList());
		if (CollectionUtils.isEmpty(userPrizeList)) {
			logger.error("【转盘抽奖】前端调用接口异常，用户实物中奖记录对应补上，skuId={}, userId={}, source={}",
					skuId, address.getUserId(), source);
			return Message.error("系统异常，请稍后重试或联系客服", null);
		}
		YgUserPrize userPrize = userPrizeList.get(0);
		long quantity = userPrize.getCount().longValue() - userPrize.getExchangeCount();
		skuInfo.setQuantity(quantity);
		Message message = ygOrderService.saveZeroOrder(skuInfo, address, platformNo, appType);
		if (!Message.isSuccess(message)) {
			logger.error("【转盘抽奖】订单提交失败，skuId={}, userId={}, source={}, errMsg={}",
					skuId, address.getUserId(), source, message.getContent());
			return message;
		}
		YgUserPrize record = new YgUserPrize();
		record.setId(userPrize.getId());
		record.setExchangeCount(userPrize.getCount().intValue());
		this.update(record);
		return message;
	}

}
